const express = require('express')
const router = express.Router()
const { MongoClient } = require('mongodb');
const cron = require('node-cron')
const { userModel, goldModel, tradeModel, positionModel, profitModel, goldHerstoryModel } = require('../model/model')
const Decimal = require('decimal.js');


const uri = "mongodb+srv://nikiisme321:t36T3Qp1aFjqTFPq@cluster0.k7soc.mongodb.net/el"
const client = new MongoClient(uri, { useNewUrlParser: true, useUnifiedTopology: true })
async function getGoldPrice() {
    try {
        const database = client.db('el');
        const collection = database.collection('quotes');
        const query = { q63: { $exists: true } };
        const projection = { q63: 1, _id: 0 };
        const doc = await collection.findOne(query, { projection });
        if (doc && doc.q63) {
            const q63Value = parseFloat(doc.q63);
            console.log(`实时金价: ${q63Value}`);
            return q63Value;
        }
        // throw new Error('未找到实时金价');
        console.log(`未找到实时金价`);
        
    } catch (err) {
        console.error('获取金价出错:', err);
        // throw err;
    }
}


//获取收盘金价
async function getEndPrice() {
    try {
        const database = client.db('el');
        const collection = database.collection('quotes');
        const query = { q2: { $exists: true } };
        const projection = { q2: 1, _id: 0 };
        const doc = await collection.findOne(query, { projection }); // 获取一条记录即可
        if (doc && doc.q2) {
            const q2Value = parseFloat(doc.q2);
            console.log(`实时金价: ${q2Value}`);
            return q2Value;
        }
        throw new Error('未找到实时金价');
    } catch (err) {
        console.error('获取金价出错:', err);
        throw err;
    }
}

// 计算克数
function calculateGrams(money, price) {

    if (price <= 0) {
        throw new Error('Invalid price');
    }
    const goldPrice = new Decimal(price);
    const buyAmount = new Decimal(money);
    const goldGrams = buyAmount.div(goldPrice).toFixed(4);

    return goldGrams
}

//判断是否下午3点之后
function isAfter3PM() {
    const now = new Date();
    const hours = now.getHours();
    return hours >= 15;
}
//获取金价确认日期
function getPriceConfirmationDate() {
    const now = new Date();
    const dayOfWeek = now.getDay();
    //如果是下午3点之后
    if (isAfter3PM()) {
        if (dayOfWeek === 5) {
            // 如果是星期五，则确认日期为下周一
            now.setDate(now.getDate() + 3);
        } else {
            // 否则确认日期为下个工作日
            now.setDate(now.getDate() + 1);
        }
    } else {
        //如果是下午3点之前，则确认日期为当天20点
        now.setDate(now.getDate());
    }
    now.setHours(20, 0, 0, 0)
    return now;
}
//获取确认买入日期
function getBuyConfirmationDate(priceConfirmationDate) {
    const date = new Date(priceConfirmationDate);
    if (date.getDay() === 5) {
        //如果确认日期是星期五，则买入日期为下周一
        date.setDate(date.getDate() + 3);
    } else {
        //否则买入日期为确认金价日期的下个工作日
        date.setDate(date.getDate() + 1);
    }
    return date;
}



router.get('/get_goldPrice', async (req, res) => {
    let goldPrice = await getGoldPrice()
    //获取金价确认日期
    const priceConfirmationDate = getPriceConfirmationDate();
    //获取确认买入日期
    const buyConfirmationDate = getBuyConfirmationDate(priceConfirmationDate);
    res.send({
        code: 200,
        goldPrice,
        priceConfirmationDate,
        buyConfirmationDate
    })
})


router.get('/get_gram', async (req, res) => {

    const { purchaseAmount } = req.query
    if (purchaseAmount != '') {
        let goldPrice = await getGoldPrice()
        let grams = calculateGrams(purchaseAmount, goldPrice)
        res.send({
            code: 200,
            grams
        })
    }
})



/* 支付 */
const AlipaySDK = require('alipay-sdk').default;
const AlipayFormData = require('alipay-sdk/lib/form').default;
const alipaySdk = new AlipaySDK({
    appId: '9021000142622638',
    privateKey: 'MIIEowIBAAKCAQEAqYEXrapi3zsiH9RJnDyfAmd5Q2b6ZKDk3m8kEfu0s0c049Iyyr+VCqpAtNMsizEEx/rEiWbnRJlUx/fyrXImsKIA9ynCOMRmFP+VBANW8HBXM9OkCaKZVdsUyo+8/pUC/Q05mHSTj5FBNJkBy8SICIpLMCxLULsbbnAZbMx+qsD6R+QCOL7lVlSBD+6GFwv4NkKJom1Ez9HA9/LXE26qOWbGqcGzMrNxmezrVVZcwgWkbALrpmF2I8nQpT1TqW3XHGvHolO0jTgNoiNcsfxPElApE2NzgH/q+nuqsb9XYS62bMMSLieRU52fHfvnNrqkKsUzAJtPIgsONZHjWbVzKQIDAQABAoIBAQCj1w7/I2nMYokagQThysrb9Q6GcxxmdgqjYoRYCZdhjtt1trC3vzUeCPDgmBo/NJNthVvBgEDc0uTbITRmKKdzJjSOs8NzQYt2kpEEPwIjCEOR6eluEsfp8AiJvyQsY/ZuiQD59vzG0d1YLOlKf94JezswBjCKiUD7n8lDm+p3utW1ajo5X2H12GW636DsPz3lwfGIevZnZFh3gJkaPRipO/kj4dUFXSt09qXt37AJHhZAyPpQlqyzAegSZ81CrDS3k9Hh8rGkOVWE6EFrofx6nLafKQeoLJhlaDhLiG1/3vvp3fF/ni9KikvcygbqTzWBYLqRLOavwnXmXT48TQOxAoGBAPebMdq9qovJr1yAVGA5p8o/ac+5fVvL4hopVuD5XVNiq8/2fWGjk37RkcmIAAEz8G5EuSsqc9L9et7WqpECWgGQEho/KCSpWd+NcY+awCx5DvjM31iB67gyCEDi4KD+cIddblvo3FCsM4vuZohbO4OT22JklAqfy+dNCIzUWFLdAoGBAK9AGqyRe0yC7rxCeUgIsD0wBMAPF6wg9AVO0SyBbO4c6W+0FVPYewGTugEkjYApSjskD/AG4+FvNbPj0pW8iNert1fX72sFs4FwOa+v7FUclPI8JcvB1Yfa4WJyKkqc5wJdTIsONY0vFIldAeQWYYKFuqRMOWlrMeTiJY64Xf69AoGAT1sB42UeH6cH+NF4OU7BI+Sm+NguARma4V+WZIwHCQ56mjAZhw1x3Bc2biyUM859pBmKbvcwH9L1ai3KhKcISa/u3VKYfwd3sloWpzulk5tI3RxsCGW7MlF2q7UK4Q4q6ndbQ0GiOoi2DIbffZwfus/MZABwIeeM5hieQORdWlECgYAOkX2mKtHdImVGMSBz5IUCESPT8208WeDvMAYjdP7hLHYbWxUKy0wubWFhBvDcXpJVKEJK6ce3zc7hDWdMG0gk5ZlwK/szIl4xvGqPOEilKqMXH/jkX1Co4oEp9eOeIDzz7V2Xka7R9b/3S0wE8fdZKlTBo7SCFu8m38XPf3QQ4QKBgCy1kPo3IAF0qOnuQ2dKV+1LzZHBeC222EmcejOf7yoRmZtQKX54ayt0g6HSK1dL305JvCblbMp03AYtoRB8qI6/PKC1UrWtOnyRaldSKzO/Sqws7FvaIPCKphWccaGY84XvQw/v+eH5e8Mdk5xMvUWMT1oUFut3euPAKCLhKkQ2',
    alipayPublicKey: 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjGy8tEICYCxIg4Dd4/aLLbkHBkQ5J4Se0coDLbcMt/CeNkNYAmft7GTQWgZntRmk20C6NZlXisOLEfGOhrKvbaxHX2N3cw3sosRWU9D7Uo0ImZVhGt/f9aSv84cgx94vnJi15tUqE4DTN8ZNS1tOmFL/CutED5PRtDIHigPiRKPNDAxZIwwT3frdHcivD8f41bRpLwL48txdJxT5WgteEUUsjVLV8Onz+yj6JtSt3j/rRKM2jx40EcF/n/zOj6ntfgagsUoffk0dgQYq5SFvcYgAZ5E3eHIAeQsRyL8ufJnYEstZPlxQj4gG/hSnX07rWU5wYpCrazqljDBqUTrHdwIDAQAB',
    gateway: 'https://openapi-sandbox.dl.alipaydev.com/gateway.do', // 沙箱环境
    charset: 'utf-8',
    signType: 'RSA2',
});


router.post('/pay', async (req, res) => {
    let { outTradeNo, totalAmount, subject, gram } = req.body
    const curtime = new Date()
    let goldPrice = await getGoldPrice()

    //获取金价确认日期
    const priceConfirmationDate = getPriceConfirmationDate();
    //获取确认买入日期
    const buyConfirmationDate = getBuyConfirmationDate(priceConfirmationDate);

    const trade = {
        userId: '6746f69f32c730833561d694',
        transactionType: 'buy',
        transactionAmount: totalAmount,
        goldAmount: gram,
        pricePerGram: goldPrice,
        status: 'pending',
        priceConfirmationDate: priceConfirmationDate,
        buyConfirmationDate: buyConfirmationDate,
        createdAt: curtime,
    }

    await tradeModel.create(trade)

    //开始对接支付宝API
    const formData = new AlipayFormData()
    //调用setMethod并传入get,会返回可以跳转到支付页面的url
    formData.setMethod('get')
    //支付时信息
    const bizContent = {
        out_trade_no: outTradeNo, //订单号
        // FAST_INSTANT_TRADE_PAY
        // QUICK_WAP_WAY
        product_code: "QUICK_WAP_WAY",
        total_amount: totalAmount, //总价格
        subject: subject, //商品名称
        body: "商品详情", //商品描述
    };
    // console.log(bizContent);

    formData.addField("bizContent", bizContent)//业务参数
    //支付成功或失败的返回链接（前端页面）
    formData.addField("returnUrl", "http://localhost:8081/order")
    formData.addField("notifyUrl", "http://192.168.43.148:3000/alipay/return");

    const result = alipaySdk.exec(

        // "alipay.trade.page.pay",
        "alipay.trade.wap.pay",
        {},
        { formData: formData }
    ).catch(error => console.error('caught error!', error));
    //支付宝对接成功 支付宝返回的数据

    result.then(async (resp) => {
        res.send({
            paymentUrl: resp,
        })
    })
})

router.get('/get_trade', async (req, res) => {
    const trades = await tradeModel.find().sort({ createdAt: -1 })
    let buysNum = 0
    let sellsNum = 0
    let buysAmount = 0
    let sellsAmount = 0
    let transactionSummary = {} //交易汇总
    trades.forEach(trade => {
        trade.transactionType == 'buy' ? buysNum++ : sellsNum++
        trade.transactionType == 'buy' ? buysAmount += trade.transactionAmount : sellsAmount += trade.transactionAmount
    })
    transactionSummary = {
        buysNum,
        sellsNum,
        buysAmount,
        sellsAmount
    }

    res.send({
        trades,
        transactionSummary
    })
}
)

router.get('/get_trade_detail', async (req, res) => {
    const { id } = req.query
    const transactionData = await tradeModel.findOne({ _id: id })
    res.send({
        transactionData
    })
})




//定时任务，自动更新交易状态,从pending到confirmed确认金价,交易日20:45执行
cron.schedule('10 19 * * 1-5', async () => {
    try {
        const currentDate = new Date();
        console.log(currentDate, 'currentDate');
        //查询所有状态为pending的交易记录
        const pendingTrades = await tradeModel.find({ status: 'pending' });
        console.log(pendingTrades, 'pendingTrades');
        for (const trade of pendingTrades) {
            const priceConfirmationDate = new Date(trade.priceConfirmationDate);
            //如果当前日期>=确认买入日期，更新状态并生成持仓记录
            const goldPrice = await getEndPrice();
            console.log(111, priceConfirmationDate);
            const grams = calculateGrams(trade.pricePerGram, goldPrice); // 计算克数
            if (currentDate >= priceConfirmationDate) {


                trade.status = 'confirmed';//更新状态为confirmed，确认金价
                trade.goldAmount = grams
                await trade.save();
            }
        }
    } catch (err) {
        console.error('定时任务出错:', err);
    }
})
//定时任务，自动更新交易状态，从confirmed到completed完成交易，并生成持仓表
cron.schedule('10 19 * * 1-5', async () => {
    try {
        const currentDate = new Date();
        //查询所有状态为confirmed的交易记录
        const pendingTrades = await tradeModel.find({ status: 'confirmed' });
        for (const trade of pendingTrades) {
            const buyConfirmationDate = new Date(trade.buyConfirmationDate);
            //如果当前日期>=确认买入日期，更新状态并生成持仓记录
            if (currentDate >= buyConfirmationDate) {
                trade.status = 'completed';//更新状态为completed，完成交易
                await trade.save();

                // 计算该用户所有已完成交易的总金额
                const completedTrades = await tradeModel.find({
                    userId: trade.userId,
                    status: 'completed'
                });
                let totalAmount = completedTrades.reduce((sum, t) => sum + t.transactionAmount, 0);

                //生成持仓记录
                await positionModel.updateOne({
                    userId: trade.userId,
                }, {
                    $set: {
                        goldAmount: trade.goldAmount,//持仓记录的黄金克数
                        buyPrice: trade.pricePerGram,//买入金价作为持仓记录的买入价
                        totalAmount: totalAmount,
                        createdAt: new Date(),
                    }

                }, {
                    upsert: true
                })
            }
        }
    } catch (err) {
        console.error('定时任务出错:', err);
    }
})
//定时任务，自动更新收益表
cron.schedule('42 19 * * 1-5', async () => {
    try {
        const position = await positionModel.find();
        //获取昨天收盘价
        const previousGoldPrice = new Decimal(await getPreviousGoldPrice());
        //获取今天收盘价
        const currentGoldPrice = new Decimal(await getTodayGoldPrice());

        for (const pos of position) {
            //当日收益金额
            const earnings = ((currentGoldPrice.minus(previousGoldPrice)).mul(new Decimal(pos.goldAmount))).toFixed(2);
            //当日时间
            const date = new Date();
            //持有收益
            const totalEarnings = ((currentGoldPrice.minus(pos.buyPrice)).mul(new Decimal(pos.goldAmount))).toFixed(2);
            //持有收益率
            const totalRate = ((currentGoldPrice.minus(pos.buyPrice)).div(new Decimal(pos.buyPrice))) * 100;
            await profitModel.updateOne({
                userId: pos.userId,
                positionId: pos._id
            }, {
                $push: {
                    dailyEarnings: [{
                        earnings: earnings,
                        date: date,
                    }],
                },
                $set: {
                    totalEarnings: totalEarnings,
                    totalRate: totalRate,
                }
            }, {
                upsert: true,//如果记录不存在则插入
            })
        }
    } catch (err) {
        console.error('定时任务出错:', err);
    }
})



//定时任务:存储每日收盘价---19:45
cron.schedule('32 19 * * 1-5', async () => {
    try {
        const currentDate = new Date();
        const goldPrice = await getEndPrice();
        await goldHerstoryModel.updateOne(
            {
                date: currentDate.toISOString().split('T')[0],
                price: goldPrice,
            }, {
            upsert: true,// 如果当日记录不存在，则插入；否则更新
        }
        );
        console.log(`收盘价已存储: 日期 ${currentDate.toISOString().split('T')[0]}, 金价 ${goldPrice}`);
    } catch (err) {
        console.error('存储每日收盘价失败:', err);
    }
})
//查询今天收盘价
async function getTodayGoldPrice() {
    try {
        const today = new Date();

        const todayPriceRecord = await goldHerstoryModel.findOne({
            date: today.toISOString().split('T')[0],
        });

        if (todayPriceRecord && todayPriceRecord.price) {
            return todayPriceRecord.price;
        }
        // throw new Error('未找到今日金价');
    } catch (err) {
        console.error('获取今日金价失败:', err);
        // throw err;
    }
}
//查询昨日收盘价
async function getPreviousGoldPrice() {
    try {
        const yesterday = new Date();
        yesterday.setDate(yesterday.getDate() - 1); // 昨天的日期

        const previousPriceRecord = await goldHerstoryModel.findOne({
            date: yesterday.toISOString().split('T')[0],
        });

        if (previousPriceRecord && previousPriceRecord.price) {
            return previousPriceRecord.price;
        }
        throw new Error('未找到昨日金价');
    } catch (err) {
        console.error('获取昨日金价失败:', err);
        throw err;
    }
}







// 获取所有收益记录
router.get('/get_profits', async (req, res) => {
    try {
        const data = await profitModel.find();
        res.send({
            data
        });
    } catch (error) {
        res.status(500).send();
    }
});





router.get('/get_position', async (req, res) => {
    let {uid} = req.query.params;
    console.log(uid,'uid5555555');
    
    let data = await positionModel.findOne({ userId: uid });
    console.log(data);
    
    let { goldAmount, buyPrice } = data

    //获取昨天收盘价
    const previousGoldPrice = await getPreviousGoldPrice();
    //获取今天收盘价
    const currentGoldPrice = await getTodayGoldPrice();

    let yesterdayProfit = ((currentGoldPrice - previousGoldPrice) * goldAmount).toFixed(2);



    let curGoldPrice = await getGoldPrice();
    let holdingProfit = ((curGoldPrice - buyPrice) * goldAmount).toFixed(2);
    let holdingProfitRate = (((curGoldPrice - buyPrice) / buyPrice) * 100).toFixed(2);

    let amountHeld = 0  //持有金额
    let TBCAmount = 0   //待确认金额

    const trades = await tradeModel.find()
    trades.forEach(trade => {
        if (trade.status == 'pending') {
            TBCAmount += trade.transactionAmount
        }
        if (trade.status == 'completed') {
            amountHeld += trade.transactionAmount
        }
    })

    let dailyincrease = (((currentGoldPrice - previousGoldPrice) / currentGoldPrice) * 100).toFixed(2)

console.log(8888,yesterdayProfit, holdingProfit, holdingProfitRate, TBCAmount, amountHeld, dailyincrease);

    let holdAll = {
        yesterdayProfit,
        holdingProfit,
        holdingProfitRate,
        TBCAmount,
        amountHeld,
        dailyincrease
    }

    res.send({
        code: 200,
        data,
        holdAll
    })


})



/* 卖出 */
router.get('/positionModel', async (req, res) => {
    let data = await positionModel.find()
    let jj = await getGoldPrice()
    console.log(data);
    console.log(jj);
    res.send({
        data, jj
    })
})
router.post('/tradeModel', async (req, res) => {
    let { q } = req.body
    let data = await positionModel.find()
    let jj = await getGoldPrice()
    console.log(data, '这是date');
    console.log(q, '这是我传过来的');
    console.log(new Date());
    let w = {
        goldAmount: new Decimal(data[0].goldAmount).sub(new Decimal(q.goldAmount)),
        buyPrice: jj,
        totalAmount:new Decimal(jj).mul(new Decimal((new Decimal(data[0].goldAmount).sub(new Decimal(q.goldAmount))))),
        updatedAt: new Date()
    }
    console.log(w.goldAmount, 'w的goldAmount');

    data[0].goldAmount = w.goldAmount
    data[0].buyPrice = w.buyPrice
    data[0].totalAmount = w.totalAmount
    data[0].updatedAt = w.updatedAt
    // let w=data[0].goldAmount-q.goldAmount
    console.log(data, '这是更新后的date');
    await positionModel.updateOne({ _id: data[0]._id }, data[0])
    await tradeModel.create(q)
    res.send({
        code: 200
    })
})


module.exports = router

